﻿Imports System.Reflection
Imports System.Collections.Generic


Public Class DOPropertyHelper
    Private m_infosLookup As String()
    Private m_infos() As DOInfo
    Private m_key As String
    Private m_type As Type
    Private m_primaryKeyPropertyName As String

    Public Sub New(ByVal t As Type)
        Me.m_type = t
        Me.m_key = t.ToString()
        Me.CacheStructure()
    End Sub

    ''' <summary>
    ''' Cache the structure of this object reflection in a high level of detail
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub CacheStructure()
        Dim myPropertyInfo() As PropertyInfo
        Dim myPropertyNames As New List(Of String)
        Dim myInfoList As New List(Of DOInfo)
        Dim tmpAttr() As Object
        myPropertyInfo = m_type.GetProperties()

        For i As Integer = 0 To myPropertyInfo.Length - 1
            If myPropertyInfo(i).DeclaringType.Equals(m_type) Then
                tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(PersistAttribute), False)
                If tmpAttr.Length > 0 Then
                    myPropertyNames.Add(myPropertyInfo(i).Name)

                    Dim element As New DOInfo
                    element.CastType = myPropertyInfo(i).DeclaringType
                    element.PropertyName = myPropertyInfo(i).Name
                    element.TypeName = myPropertyInfo(i).PropertyType.ToString()
                    tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(PrimaryKeyAttribute), False)
                    element.PrimaryKey = IIf(tmpAttr.Length > 0, True, False)
                    tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(IdentityAttribute), False)
                    element.Identity = IIf(tmpAttr.Length > 0, True, False)
                    element.Index = i

                    'Put validation attribute mappers here
                    tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(BizBloxValidatorAttribute), False)
                    If tmpAttr.Length > 0 Then
                        Dim tmpValidator As BizBloxValidatorAttribute = Nothing
                        For j As Integer = 0 To tmpAttr.Length - 1
                            'try?
                            tmpValidator = CType(tmpAttr([j]), BizBloxValidatorAttribute)
                            tmpValidator.PropertyName = element.PropertyName
                            element.Validators.Add(tmpValidator)
                        Next
                    End If
                    myInfoList.Add(element)
                    If element.PrimaryKey Then m_primaryKeyPropertyName = element.PropertyName
                End If
            End If
        Next
        m_infosLookup = myPropertyNames.ToArray()
        m_infos = myInfoList.ToArray()
    End Sub

    Public Function IsIdentity(ByVal propertyIndex As Integer) As Boolean
        Return m_infos(propertyIndex).Identity
    End Function

    Public Function IsIdentity(ByVal propertyName As String) As Boolean
        Return Me.IsIdentity(Array.IndexOf(m_infosLookup, propertyName))
    End Function

    Public Function IsPrimaryKey(ByVal propertyIndex As Integer) As Boolean
        Return m_infos(propertyIndex).PrimaryKey
    End Function

    Public Function IsPrimaryKey(ByVal propertyName As String) As Boolean
        Return Me.IsPrimaryKey(Array.IndexOf(m_infosLookup, propertyName))
    End Function

    Public Function IsPersistant(ByVal propertyName As String) As Boolean
        Return m_infosLookup.Contains(propertyName)
    End Function

    Public ReadOnly Property DOTypeName() As String
        Get
            Return Me.m_key
        End Get
    End Property

    Public ReadOnly Property PropertyInfo() As DOInfo()
        Get
            Return Me.m_infos
        End Get
    End Property

    Public ReadOnly Property PropertyInfoCount() As Integer
        Get
            Return Me.m_infos.Length
        End Get
    End Property

    Public Function GetInfo(ByVal index As Integer) As DOInfo
        Return Me.m_infos(index)
    End Function

    Public Function GetInfo(ByVal propertyName As String) As DOInfo
        Return Me.m_infos((Array.IndexOf(m_infosLookup, propertyName)))
    End Function

    Public ReadOnly Property PrimaryKeyName() As String
        Get
            Return Me.m_primaryKeyPropertyName
        End Get
    End Property


End Class
